---
title: P
date: 2022-06-01
description: 一个支持语法高亮的文本粘贴网站
demo: https://p.elianiva.my.id
source: https://github.com/elianiva/p
type: personal
featured: true
stack:
    - ["Typescript", "https://typescriptlang.org"]
    - ["CF Workers", "https://www.cloudflare.com/workers/"]
    - ["CF KV", "https://developers.cloudflare.com/workers/runtime-apis/kv/"]
---

**P**（很有创意的名字，我知道）是一个您可以粘贴文本并支持语法高亮的网站。

这是使用[Cloudflare Workers](https://www.cloudflare.com/workers/)和[Cloudflare KV](https://developers.cloudflare.com/workers/runtime-apis/kv/)作为存储制作的。我制作这个是因为我想学习如何使用Cloudflare Workers和Cloudflare KV。之前我使用[Polarite](https://github.com/teknologi-umum/polarite)来粘贴我的文本，但由于分布式数据库很难或其他类似的原因，它突然坏了。

我最初考虑使用Rust，但最终没有使用它，因为我意识到Cloudflare KV的Rust适配器只是包装了JavaScript适配器，所以有很多数据类型来回转换，所以我最终选择了Typescript。

我还使用它来学习如何在阅读Robert C. Martin的《清洁架构：软件结构工匠指南》后应用清洁架构，这是一本好书。
它可能对这种简单的项目来说有点过头了，但我发现它相当有趣。我喜欢将项目分层的想法，我认为这会让项目保持整洁和可维护。

书中有一部分讨论了为什么你应该依赖抽象而不是具体实现。如果你这样做，你可以在以后选择如何实现该抽象，而你可以专注于核心逻辑。你还可以有多个实现并在运行时选择使用哪一个。

在这个项目中，我使用了`IStorage`和`IHighlighter`来抽象存储和语法高亮。我有一个`MemoryStorage`类，它实现了`IStorage`接口，我在开始时使用它，而不是实际实现Cloudflare KV存储。我还使用了一个`DumbHighlighter`，它实现了`IHighlighter`，这样我可以在不实现实际逻辑的情况下测试它如何处理不同语言的高亮，它只是根据语言参数添加前缀。以这种方式工作非常愉快。

我添加了一堆`Response`对象包装器，因为我喜欢AspNetCore样式的返回响应。你只需要返回`Ok("response text")`来表示200响应，而不是`Response("response", { status: 200 })`。它们还会自动处理JSON序列化和适当的头信息。
